/**
 * @integralImageConvolution.h
 * @brief Questo header contiene le dichiararioni delle funzioni per l'applicazione
 * di un filtro gaussiano sfruttando la tecnica dell'immagine integrale
 *
 * 
 *
 * @date 22/11/2012
 */

#ifndef INTEGRALIMAGECONVOLUTION_H
#define INTEGRALIMAGECONVOLUTION_H

#include "opencv2/opencv.hpp"
#include <fstream>

using namespace cv;
using namespace std;

const int NPASSES = 5; /** <Numero di applicazione del filtro mediano */

/**
 * Metodo che esegue il calcolo dell'immagine integrale, cioe' l'immagine il cui pixel di
 * coordinate (x,y) ha un valore dato dalla somma di tutti i valori dei pixel 
 * dell'immagine originale che si trovano sopra e a sinistra di esso.
 * Questo metodo è molto utile per calcolare efficientemente la somma dei valori
 * che si trovano all'interno di sottoinsieme rettangolare dell'immagine 
 * @author Lorenzo
 * @param image immagine originale
 * @param intImg immagine integrale risultante
 * @date 22/11/2012
 */
void calcIntegralImage(const Mat_<uchar>& image, Mat_<int>& intImg);
/**
 * Metodo ottimizzato per il calcolo dell'immagine integrale utilizzando i puntatori
 * per accedere ai dati delle immagini
 * @author Lorenzo
 * @param image immagine originale
 * @param intImg immagine integrale risultante
 * @date 22/11/2012
 */
void calcIntegralImagePoint(const Mat_<uchar>& image, Mat_<int>& intImg);

/**
 * Metodo che esegue il calcolo dell'immagine risultante dopo l'applicazione di un filtro mediano.
 * Il calcolo viene effettuato sfruttando la tecnica dell'immagine integrale per ridurre il numero
 * di operazioni di somma effettuate ad ogni passo
 * @author Lorenzo
 * @param intImg immagine integrale precedentemente calcolata
 * @param imgOut immagine risultante
 * @param kern_dim dimensioni del kernel da applicare
 * @date 22/11/2012
 */
void medianFilterIntegImage(const Mat_<int> &intImg, Mat_<uchar> &imgOut, const int kern_dim);
/**
 * Metodo ottimizzato per l'applicazione di un filtro mediano utilizzando i puntatori
 * per accedere ai dati delle immagini
 * @author Lorenzo
 * @param intImg immagine integrale precedentemente calcolata
 * @param imgOut immagine risultante
 * @param kern_dim dimensioni del kernel da applicare
 * @date 22/11/2012
 */
void medianFilterIntegImagePoint(const Mat_<int> &intImg, Mat_<uchar> &imgOut, const int kern_dim);

/**
 * Metodo che esegue il calcolo dell'immagine risultante dopo l'applicazione di un filtro Gaussiano.
 * Il calcolo viene eseguito sfruttando la tecnica dell'immagine integrale e l'applicazione ripetuta
 * di un filtro mediano al fine di ottenere una buona approssimazione di un Gaussian Filter
 * @author Lorenzo
 * @param imgIn immagine originale
 * @param imgOut immagine risultante
 * @param sigma deviazione standard del filtro gaussiano da applicare
 * @date 22/11/2012
 */
void integralImgGaussianConv(const Mat_<uchar>& imgIn, Mat_<uchar>& imgOut, const double sigma);
/**
 * Metodo ottimizzato per l'applicazione di un filtro gaussiano tramite tecnica integral image
 * che utilizza i puntatori per accedere ai dati delle immagini
 * @author Lorenzo
 * @param imgIn immagine originale
 * @param imgOut immagine risultante
 * @param sigma deviazione standard del filtro gaussiano da applicare
 * @date 22/11/2012
 */
void integralImgGaussianConvPoint(const Mat_<uchar>& imgIn, Mat_<uchar>& imgOut, const double sigma);

double round(double x);

#endif // INTEGRALIMAGECONVOLUTION_H
